#!/usr/bin/python
# -*- coding: UTF-8 -*-

import sys, os, time

from loguru import logger

from PyQt5.QtWidgets import QApplication, QWidget, QLCDNumber
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtCore import QTimer

from qt_material import apply_stylesheet

sys.path.append(os.getcwd())
from views.widgets import Ui_sequence_control
from utils import serialport_com

#打开串口
#AT                      %测试串口通信及初始化:
#AT+CH1+OUT+0            %通道1 关闭
#AT+CH0+OUT+0            %通道0 关闭

#开启Flash（等10s后才能开启Q-Switch）
#AT+CH0+RT+0                    %通道0 上升沿起始延迟0ns
#AT+CH0+WID+100000              %通道0 脉宽100000ns 100μs
#AT+CH0+CYCLE+100000000         %通道0 周期100ms
#AT+CH0+OUT+1                   %通道0 开启

#开启Q-Switch（开启Q-Switch后不能关闭Flash）
#AT+CH1+RT+400000          %通道1 上升沿起始延迟400000ns（通道1与通道0默认同步，通道1上升沿相对通道0上升沿的典型延迟值：400000ns~260000ns）
#AT+CH1+WID+100000         %通道1 脉宽100000ns 100μs
#AT+CH1+CYCLE+100000000    %通道1 周期100ms
#AT+CH1+OUT+1              %通道1 开启

#关闭Q-Switch
#AT+CH1+OUT+0                        %通道1 关闭

#关闭Flash
#AT+CH0+OUT+0                        %通道0 关闭


class SequenceControlForm(QWidget, Ui_sequence_control.Ui_SequenceControlForm):

    MIMUM_WAITING_TIME = 10

    def __init__(self, parent = None):
        super(SequenceControlForm, self).__init__(parent)
        self.setupUi(self)

        #获取可用的串口
        self.serialPortCom = serialport_com.SerialPortCom()
        portcom = self.serialPortCom.port_check()
        if len(portcom) > 0:
            for key in portcom.keys():
                self.ChooseCOM.addItem(key)

        # 设置默认的延迟值
        self.DelayTimeEdit.setText("400")

        # 设置倒数计数器
        self.lcdTimer.setDigitCount(2)
        self.lcdTimer.setSegmentStyle(QLCDNumber.Flat)
        self.lcdTimer.setStyleSheet("border: 2px solid black; color: red; background: silver;")
        self.__timer = QTimer(self)
        self.__timer.setInterval(1000)
        self.__timer.timeout.connect(self.refreshLCD)
        self.leftSeconds = self.MIMUM_WAITING_TIME   # waiting time
        self.lcdTimer.display(self.leftSeconds)

        self.parentMainWindow = None

        self.NestStepButton.clicked.connect(self.nextStep)
        self.LastStepButton.clicked.connect(self.lastStep)

        # 为按钮设置响应函数
        self.OpenSerialButton.clicked.connect(self.openSerial)
        self.OpenFlashButton.clicked.connect(self.openFlash)
        self.OpenQSwitchButton.clicked.connect(self.openQSwitch)
        self.CloseQSwitchButton.clicked.connect(self.closeQSwitch)
        self.CloseFlashButton.clicked.connect(self.closeFlash)

        # disable the buttons defaultly
        self.OpenFlashButton.setEnabled(False)
        self.OpenQSwitchButton.setEnabled(False)
        self.CloseQSwitchButton.setEnabled(False)
        self.CloseFlashButton.setEnabled(False)

        logger.debug("create an instance of SequenceControlForm successfully")     

    def setMainWindow(self, MainWindow):
        self.parentMainWindow = MainWindow

    def lastStep(self):
        if self.parentMainWindow is not None:
            self.parentMainWindow.sequenceControlLastStep()
        else:
            pass
    
    def nextStep(self):
        if self.parentMainWindow is not None:
            self.parentMainWindow.sequenceControlNextStep()
        else:
            pass
    
    def refreshLCD(self):
        if self.leftSeconds == 0:
            return

        self.leftSeconds -= 1
        self.lcdTimer.display(self.leftSeconds)

        if self.leftSeconds == 0:
            self.__timer.stop()
            #self.OpenFlashButton.setEnabled(True)
            self.OpenQSwitchButton.setEnabled(True)
            #self.CloseQSwitchButton.setEnabled(True)
            self.CloseFlashButton.setEnabled(True)
            return
    
    def resetLCD(self):
        self.__timer.stop()
        self.lcdTimer.display(self.leftSeconds)

    #打开串口
    #AT                      %测试串口通信及初始化:
    #AT+CH1+OUT+0            %通道1 关闭
    #AT+CH0+OUT+0            %通道0 关闭
    def openSerial(self):
        portname = self.ChooseCOM.currentText()
        baudrate = 115200
        bytesize = 8
        stopbits = 1
        parity = "N"
        if not self.serialPortCom.port_open(portname, baudrate, bytesize, stopbits, parity):
            logger.error("Port Error: 此设备串口不能被打开！")
            QMessageBox.critical(self, "Port Error", "此串口不能被打开！")
            return

        if not self.sendDataCheck("AT"):
            return

        if not self.sendDataCheck( "AT+CH1+OUT+0"):
            return

        if not self.sendDataCheck("AT+CH0+OUT+0"):
            return

        #打开串口成功后 OpenFlash 使能
        self.OpenFlashButton.setEnabled(True)        
        logger.debug("SequenceControlForm.openSerial succeeds. ")


    #开启Flash（等10s后才能开启Q-Switch）
    #AT+CH0+RT+0                    %通道0 上升沿起始延迟0ns
    #AT+CH0+WID+100000              %通道0 脉宽100000ns 100μs
    #AT+CH0+CYCLE+100000000         %通道0 周期100ms
    #AT+CH0+OUT+1                   %通道0 开启
    def openFlash(self):
        if not self.sendDataCheck("AT+CH0+RT+0"):
            return
        
        if not self.sendDataCheck("AT+CH0+WID+100000"):
            return

        if not self.sendDataCheck("AT+CH0+CYCLE+100000000"):
            return
        
        if not self.sendDataCheck("AT+CH0+OUT+1"):
            return
        
        self.__timer.start()
        self.CloseFlashButton.setEnabled(True)
        logger.debug("SequenceControlForm.openFlash succeeds. ")
        

    #开启Q-Switch（开启Q-Switch后不能关闭Flash）
    #AT+CH1+RT+400000          %通道1 上升沿起始延迟400000ns（通道1与通道0默认同步，通道1上升沿相对通道0上升沿的典型延迟值：400000ns~260000ns）
    #AT+CH1+WID+100000         %通道1 脉宽100000ns 100μs
    #AT+CH1+CYCLE+100000000    %通道1 周期100ms
    #AT+CH1+OUT+1              %通道1 开启
    def openQSwitch(self):
        try:
            delaytime_ns = int(self.DelayTimeEdit.text()) * 1000
        except:
            logger.exception("set delay time invalidly")
            return

        strATCH1RT = str("AT+CH1+RT+") + str(delaytime_ns)

        if not self.sendDataCheck(strATCH1RT):
            return

        if not self.sendDataCheck("AT+CH1+WID+100000"):
            return

        if not self.sendDataCheck("AT+CH1+CYCLE+100000000"):
            return

        if not self.sendDataCheck("AT+CH1+OUT+1"):
            return

        self.CloseFlashButton.setEnabled(False)
        self.CloseQSwitchButton.setEnabled(True)
        logger.debug("SequenceControlForm.openQSwitch succeeds. ")

    #关闭Q-Switch
    #AT+CH1+OUT+0                        %通道1 关闭
    def closeQSwitch(self):
        if not self.sendDataCheck("AT+CH1+OUT+0"):
            return

        self.CloseFlashButton.setEnabled(True)
        logger.debug("SequenceControlForm.closeQSwitch succeeds. ")

    #关闭Flash
    #AT+CH0+OUT+0                        %通道0 关闭
    def closeFlash(self):
        if not self.sendDataCheck("AT+CH0+OUT+0"):
            return
        
        self.OpenQSwitchButton.setEnabled(False)
        self.CloseQSwitchButton.setEnabled(False)
        self.leftSeconds = self.MIMUM_WAITING_TIME
        self.resetLCD()
        logger.debug("SequenceControlForm.closeFlash succeeds. ")

    def sendDataCheck(self, sendData):
        mode = "ASCII"

        send_data_len = self.serialPortCom.data_send(mode, sendData)
        if not((len(sendData) + 2) == send_data_len):
            logger.error("Port Error: 串口数据发送失败！发送数据为：{}" + sendData)
            QMessageBox.critical(self, "Port Error", "串口数据发送失败！发送数据为：" + sendData)
            return False

        time.sleep(0.05)
        
        receive_data =  self.serialPortCom.data_receive(mode)
        if receive_data.endswith("OK"):
            logger.error("Port Error: 串口数据接收异常：{}" + receive_data)
            QMessageBox.critical(self, "Port Error", "串口数据接收异常：" + receive_data)
            return False

        return True



if __name__ == "__main__":
    app = QApplication(sys.argv)
    PAWin = SequenceControlForm()
    apply_stylesheet(app, theme = "dark_teal.xml")
    PAWin.show()
    sys.exit(app.exec_())